package org.agbe;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.util.Log;

public class MediaPlayerPool {

	private final Context context;

	private final Map<String, Integer> resourceIdByNames = new HashMap<String, Integer>();

	private static final int MAX_MEDIAPLAYERS_NUMBER = 3;

	private final List<MediaPlayerContext> ctxs = new ArrayList<MediaPlayerContext>();

	public MediaPlayerPool(Context context) {
		this.context = context;
	}

	public void init() {
		Log.i(AgbeGame.AGBE_LOGNAME, "Initialisation du pool de MediaPlayer");
		for (int i = 0; i < MAX_MEDIAPLAYERS_NUMBER; i++) {
			MediaPlayerContext mpc = new MediaPlayerContext(context);
			mpc.init();
			ctxs.add(mpc);
		}
		registerSounds();
	}

	private void registerSounds() {
		registerSound("sound/mer.ogg", R.raw.mer);
		registerSound("sound/gun.ogg", R.raw.gun);
		registerSound("sound/slap.ogg", R.raw.slap);
	}

	private void registerSound(String key, Integer resId) {
		resourceIdByNames.put(key, resId);
	}

	public void playSound(String soundfilePath, int iteration) {
		Log.d(AgbeGame.AGBE_LOGNAME, "playSound called with " + soundfilePath
				+ " and " + iteration + " iterations.");
		Integer resourceId = computeResourceId(soundfilePath);
		boolean soundPlayed = false;
		if (resourceId != null) {
			MediaPlayerContext mostAncientPlayingCtx = null;
			for (int i = 0; i < MAX_MEDIAPLAYERS_NUMBER; i++) {
				MediaPlayerContext mpc = ctxs.get(i);
				if (!mpc.isPlaying()) {
					soundPlayed = true;
					mpc.playSound(resourceId, iteration);
					break;
				}
				if (mostAncientPlayingCtx == null) {
					mostAncientPlayingCtx = mpc;
				} else if (mostAncientPlayingCtx != null) {
					Date ancientDate = mostAncientPlayingCtx.getPlayStartDate();
					Date mpcDate = mpc.getPlayStartDate();
					if (ancientDate != null && mpcDate != null
							&& ancientDate.after(mpcDate)) {
						mostAncientPlayingCtx = mpc;
					}
				}
			}
			if (!soundPlayed && mostAncientPlayingCtx != null) {
				mostAncientPlayingCtx.stopSound();
				soundPlayed = true;
				mostAncientPlayingCtx.playSound(resourceId, iteration);
			}
			if (!soundPlayed) {
				Log.e(AgbeGame.AGBE_LOGNAME,
						"MediaPlayerPool : Impossible to play sound because no adequate MediaPLayer has been found.");
			}
		} else {
			Log.e(AgbeGame.AGBE_LOGNAME,
					"Impossible de find sound matching with " + soundfilePath);
		}

	}

	private Integer computeResourceId(String soundfilePath) {
		Integer result = null;
		result = resourceIdByNames.get(soundfilePath);
		return result;
	}

	public void stopAllSounds() {
		for (int i = 0; i < MAX_MEDIAPLAYERS_NUMBER; i++) {
			MediaPlayerContext mpc = ctxs.get(i);
			mpc.stopSound();
		}
	}

	public void pauseAllSounds() {
		for (int i = 0; i < MAX_MEDIAPLAYERS_NUMBER; i++) {
			MediaPlayerContext mpc = ctxs.get(i);
			mpc.pauseSound();
		}
	}

	public void resumeAllSounds() {
		for (int i = 0; i < MAX_MEDIAPLAYERS_NUMBER; i++) {
			MediaPlayerContext mpc = ctxs.get(i);
			mpc.resumeSound();
		}
	}

}
